<?php
/**
 * Copyright (c) 2018-2019.
 *  This file is part of the moonpie production
 *  (c) johnzhang <875010341@qq.com>
 *  This source file is subject to the MIT license that is bundled
 *  with this source code in the file LICENSE.
 */

namespace moonpie\plugin\wechat_account\model;


use app\common\model\BaseModel;
use EasyWeChat\Kernel\Support\Arr;
use think\Db;

/**
 * 公众号用户信息模型
 * @package moonpie\plugin\wechat_account\model
 */
class WechatAccountUser extends BaseModel
{
    public static function syncFromProfile(WechatAccount $account, $openid, $withProfile = false)
    {
        //首先，检测是否存在记录，如果存在的话，那么需要同步他的昵称，头像性别省市标签信息
        $record = static::where('openid', $openid)
            ->find();
        if (!$record) {
            $data['account_id'] = $account->getId();
            $record = new static();
        }
        if ($withProfile) {
            $service = $account->getService();
            $response = $service->user->get($openid);
            if (Arr::has($response, 'errcode')) {
                $account->setModelError(sprintf('获取公众号用户信息出现错误：%s(code: %s)', Arr::get($response, 'errmsg', '未知错误'), $response['errcode']));
                return false;
            }
            $data = $response;
            $tags = [];
            if (Arr::get($response, 'subscribe')) {
                $data['avatar'] = $response['headimgurl'];
                $data['subscribe_at'] = $response['subscribe_time'];
                $tags = $data['tagid_list'];
            }

            $data = Arr::except($data, ['headimgurl', 'subscribe_time', 'qr_scene_str', 'qr_scene', 'remark', 'groupid', 'tagid_list']);
        } else {
            $data = ['openid' => $openid, 'account_id' => $account->getId()];
            $tags = [];
        }
        static::startTrans();
        try {
            $result = false !== $record->save($data);
            if (!$result) {
                static::rollback();
                $account->setModelError(sprintf('获取公众号用户信息出现错误：%s.', '无法保存获取到的用户信息'));
                return false;
            }
            //用户信息保存成功后，同步他的标签信息
            $result = $record->syncUserTags($tags);
            if (!$result) {
                static::rollback();
                $account->setModelError(sprintf('获取公众号用户信息出现错误：%s.', '无法同步用户标签信息'));
                return false;
            }
            static::commit();
            return $record;
        } catch (\Exception $e) {
            static::rollback();
            $account->setModelError(sprintf('获取公众号用户信息出现异常：%s(code: %s)', $e->getMessage(), $e->getCode()));
            return false;
        }
    }

    public function syncUserTags(array $tags)
    {
        $table = Db::name('wechat_account_user_tags');
        if (empty($tags)) {
            return false !== $table->where('wxuser_id', $this->getId())
                    ->delete();
        }
        $now = time();
        $result = false !== $table->where('wxuser_id', $this->getId())
                ->whereNotIn('tag_id', $tags)->delete();
        if (!$result) {
            return false;
        }
        foreach ($tags as $tag_id) {
            $has_one = $table->where('wxuser_id', $this->getId())
                    ->where('tag_id', $tag_id)->count() > 0;
            if (!$has_one) {
                $result = false !== $table->insert(['wxuser_id' => $this->getId(), 'tag_id' => $tag_id, 'create_at' => $now, 'update_at' => $now]);
                if (!$result) {
                    return false;
                }
            }
        }
        return true;
    }

    public static function batchSyncFromProfile(WechatAccount $account, array $openids)
    {
        $service = $account->getService();
        $response = $service->user->select($openids);

        if (Arr::has($response, 'errcode')) {
            $account->setModelError(sprintf('批量获取公众号用户信息出现错误：%s(code: %s)', Arr::get($response, 'errmsg', '未知错误'), $response['errcode']));
            return false;
        }
        $user_list = Arr::get($response, 'user_info_list', []);
        static::startTrans();
        foreach($user_list as $user) {
            $openid = $user['openid'];
            //首先，检测是否存在记录，如果存在的话，那么需要同步他的昵称，头像性别省市标签信息
            $record = static::where('openid', $openid)
                ->find();
            if (!$record) {
                $data['account_id'] = $account->getId();
                $record = new static();
            }
            $data = $user;
            $tags = [];
            if (Arr::get($user, 'subscribe')) {
                $data['avatar'] = $user['headimgurl'];
                $data['subscribe_at'] = $user['subscribe_time'];
                $tags = $data['tagid_list'];
            }

            $data = Arr::except($data, ['headimgurl', 'subscribe_time', 'qr_scene_str', 'qr_scene', 'remark', 'groupid', 'tagid_list']);
            try {
                $result = false !== $record->save($data);
                if (!$result) {
                    static::rollback();
                    $account->setModelError(sprintf('获取公众号用户信息出现错误：%s.', '无法保存获取到的用户信息'));
                    return false;
                }
                //用户信息保存成功后，同步他的标签信息
                $result = $record->syncUserTags($tags);
                if (!$result) {
                    static::rollback();
                    $account->setModelError(sprintf('获取公众号用户信息出现错误：%s.', '无法同步用户标签信息'));
                    return false;
                }
            } catch (\Exception $e) {
                static::rollback();
                $account->setModelError(sprintf('获取公众号用户信息出现异常：%s(code: %s)', $e->getMessage(), $e->getCode()));
                return false;
            }
        }
        static::commit();
        return true;
    }
    public function getSexAttr($sex)
    {
        static $map = [0 => '未知', 1 => '男', 2 => '女'];
        return Arr::get($map, $sex, '错误映射');
    }
}
